home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 April: Mac OS SDK / Dev.CD Apr 97 SDK1.toast / Development Kits (Disc 1) / Apple Game Sprockets / RAVE SDK 1.06 GM for MacOS / Example Projects / RaveTest / RAVE_MipMap.c next >
Encoding:
C/C++ Source or Header  |  1996-02-23  |  6.3 KB  |  299 lines  |  [TEXT/MPS ]

  1. /******************************************************************************
  2.  **                                                                             **
  3.  **     Module:        RAVE_MipMap.c                                             **
  4.  **                                                                          **
  5.  **     Purpose:     Support file for mipmapping                              **
  6.  **                                                                          **
  7.  **     Author:        Mike W. Kelley                                             **
  8.  **                                                                             **
  9.  **                    2/3/95    Revised for 0.9 SDK release                         **
  10.  **                    2/23/96 BHP - Revised for 1.05 relase                     **
  11.  **                                                                          **
  12.  **     Copyright (C) 1994-95 Apple Computer, Inc.  All rights reserved.     **
  13.  **                                                                          **
  14.  *****************************************************************************/
  15.  
  16. #include <stdlib.h>
  17. #include <math.h>
  18. #include <string.h>
  19. #include <stdio.h>
  20.  
  21. /* Macintosh */
  22. #include <Types.h>
  23. #include <Resources.h>
  24. #include <QuickDraw.h>
  25. #include <Fonts.h>
  26. #include <Events.h>
  27. #include <Windows.h>
  28. #include <Menus.h>
  29. #include <TextEdit.h>
  30. #include <Dialogs.h>
  31. #include <Desk.h>
  32. #include <ToolUtils.h>
  33. #include <Memory.h>
  34. #include <SegLoad.h>
  35. #include <Files.h>
  36. #include <OSUtils.h>
  37. #include <OSEvents.h>
  38. #include <DiskInit.h>
  39. #include <Packages.h>
  40.  
  41. /* Project */
  42. #include "RAVE.h"
  43. #include "RAVE_Test.h"
  44.  
  45. /*******************************************************************************************
  46.  *
  47.  * Create the mipmap for 'pixmap', and load it into 'texture'. Returns NULL on error.
  48.  *
  49.  ******************************************************************************************/
  50.  
  51. TQATexture *CreateMipMapTexture (
  52.     TQAEngine        *engine,
  53.     TexturePixel    *pixmap,
  54.     long            rowBytes,
  55.     long            widthNBits,
  56.     long            heightNBits)
  57. {
  58.     long            nImages;
  59.     long            width, height;
  60.     long            nPixels;
  61.     TexturePixel    *mipmap;
  62.     TQAImage        images [20];        /* Maximum conceivable number of TQAImages! */
  63.     long            i;
  64.     long            x, y;
  65.     long            oneHalf;
  66.     TQATexture        *texture;
  67.     TQAError        status;
  68.     
  69.     /*
  70.      * Allocate working space for the mip map images (starting with the
  71.      * 2^(widthNBits-1) x 2^(heightNBits-1) map), and for the array of
  72.      * TQAImages that describe the mip map and the parent map.
  73.      */
  74.     
  75.     nImages = ((widthNBits > heightNBits) ? widthNBits : heightNBits) + 1;
  76.     
  77.     width = 1 << (widthNBits - 1);        /* ??? Doesn't work for nBits == 0 */
  78.     height = 1 << (heightNBits - 1);    /* ??? Doesn't work for nBits == 0 */
  79.     
  80.     for (i = nImages - 1, nPixels = 0; i-- > 0; /* Nothing */)
  81.     {
  82.         nPixels += width * height;
  83.         
  84.         width >>= 1;
  85.         height >>= 1;
  86.         
  87.         if (width == 0)
  88.         {
  89.             width = 1;
  90.         }
  91.         if (height == 0)
  92.         {
  93.             height = 1;
  94.         }
  95.     }
  96.  
  97.     if ( ! (mipmap = (TexturePixel *) malloc (sizeof (*pixmap) * nPixels)))
  98.     {
  99.         return (NULL);
  100.     }
  101.     
  102.     /*
  103.      * Fill in the TQAImage info.
  104.      */
  105.     
  106.     images[0].width = 1 << widthNBits;
  107.     images[0].height = 1 << heightNBits;
  108.     images[0].pixmap = pixmap;
  109.     images[0].rowBytes = rowBytes;
  110.     
  111.     width = 1 << (widthNBits - 1);        /* ??? Doesn't work for nBits == 0 */
  112.     height = 1 << (heightNBits - 1);    /* ??? Doesn't work for nBits == 0 */
  113.     
  114.     for (i = 1; i < nImages; ++i)
  115.     {
  116.         images[i].width = width;
  117.         images[i].height = height;
  118.         images[i].pixmap = mipmap;
  119.         images[i].rowBytes = width * sizeof (*mipmap);
  120.         
  121.         mipmap += width * height;
  122.         
  123.         width >>= 1;
  124.         height >>= 1;
  125.         
  126.         if (width == 0)
  127.         {
  128.             width = 1;
  129.         }
  130.         if (height == 0)
  131.         {
  132.             height = 1;
  133.         }
  134.     }
  135.  
  136.     /*
  137.      * oneHalf is used to round off the box filter of four pixels.
  138.      */
  139.     
  140.     oneHalf = 4 / 2;
  141.  
  142.     /*
  143.      * Create the mipmapped images.
  144.      */
  145.     
  146.     for (i = 1; i < nImages; ++i)
  147.     {
  148.         TQAImage        *prevImage, *image;
  149.         long            sourceRowBytes, targetRowBytes;
  150.         unsigned char    *sourceLine0, *sourceLine1;
  151.         unsigned char    *targetLine;
  152.         
  153.         prevImage = &images [i - 1];
  154.         image = &images [i];
  155.         
  156.         sourceLine0 = (unsigned char *) prevImage->pixmap;
  157.         
  158.         if (prevImage->height == 1)
  159.         {
  160.             /*
  161.              * Source image is height 1 (widthNBits must be greater than heightNBits).
  162.              * Make sourceLine1 duplicate sourceLine0, and set sourceRowBytes to 0 so we
  163.              * just keep re-reading the single source line.
  164.              */
  165.             
  166.             sourceRowBytes = 0;
  167.             sourceLine1 = sourceLine0;
  168.         }
  169.         else
  170.         {
  171.             /*
  172.              * Normal case. sourceLine1 points one scanline above sourceLine0.
  173.              */
  174.             
  175.             sourceRowBytes = prevImage->rowBytes;
  176.             sourceLine1 = sourceLine0 + sourceRowBytes;
  177.         }
  178.         
  179.         targetRowBytes = image->rowBytes;
  180.         targetLine = (unsigned char *) image->pixmap;
  181.  
  182.         for (y = image->height; y-- > 0; /* Nothing */)
  183.         {
  184.             unsigned char    *sourcePixel0, *sourcePixel1;
  185.             unsigned char    *targetPixel;
  186.             
  187.             sourcePixel0 = sourceLine0;
  188.             sourcePixel1 = sourceLine1;
  189.             targetPixel = targetLine;
  190.             
  191.             if (prevImage->width == 1)
  192.             {
  193.                 /*
  194.                  * Source image has width 1 (heightNBits must be greater than widthNBits).
  195.                  * Use a special inner loop that doesn't advance past the first pixel of
  196.                  * the source lines.
  197.                  */
  198.                 
  199.                 for (x = image->width; x-- > 0; /* Nothing */)
  200.                 {
  201.                     long    a, r, g, b;
  202.                     
  203.                     /*
  204.                      * Read and average two pixels from source into target.
  205.                      */
  206.                     
  207.                     a = sourcePixel0 [0] + (oneHalf >> 1);
  208.                     r = sourcePixel0 [1] + (oneHalf >> 1);
  209.                     g = sourcePixel0 [2] + (oneHalf >> 1);
  210.                     b = sourcePixel0 [3] + (oneHalf >> 1);
  211.                     
  212.                     a += sourcePixel1 [0];
  213.                     r += sourcePixel1 [1];
  214.                     g += sourcePixel1 [2];
  215.                     b += sourcePixel1 [3];
  216.                     
  217.                     *targetPixel++ = a >> 1;
  218.                     *targetPixel++ = r >> 1;
  219.                     *targetPixel++ = g >> 1;
  220.                     *targetPixel++ = b >> 1;
  221.                 }
  222.             }
  223.             else
  224.             {
  225.                 /*
  226.                  * Source image has at least width 2. This is the normal case.
  227.                  */
  228.                 
  229.                 for (x = image->width; x-- > 0; /* Nothing */)
  230.                 {
  231.                     long    a, r, g, b;
  232.                     
  233.                     /*
  234.                      * Read and average four pixels from source into target.
  235.                      */
  236.                     
  237.                     a = *sourcePixel0++ + oneHalf;
  238.                     r = *sourcePixel0++ + oneHalf;
  239.                     g = *sourcePixel0++ + oneHalf;
  240.                     b = *sourcePixel0++ + oneHalf;
  241.                     
  242.                     a += *sourcePixel1++;
  243.                     r += *sourcePixel1++;
  244.                     g += *sourcePixel1++;
  245.                     b += *sourcePixel1++;
  246.                     
  247.                     a += *sourcePixel0++;
  248.                     r += *sourcePixel0++;
  249.                     g += *sourcePixel0++;
  250.                     b += *sourcePixel0++;
  251.                     
  252.                     a += *sourcePixel1++;
  253.                     r += *sourcePixel1++;
  254.                     g += *sourcePixel1++;
  255.                     b += *sourcePixel1++;
  256.                     
  257.                     *targetPixel++ = a >> 2;
  258.                     *targetPixel++ = r >> 2;
  259.                     *targetPixel++ = g >> 2;
  260.                     *targetPixel++ = b >> 2;
  261.                 }
  262.             }
  263.             sourceLine0 += (sourceRowBytes << 1);
  264.             sourceLine1 += (sourceRowBytes << 1);
  265.             targetLine += targetRowBytes;
  266.         }
  267.     }
  268.     
  269.     status = QATextureNew (engine, kQATexture_Mipmap, kQAPixel_RGB32, images, &texture);
  270.     if (status != kQANoErr)
  271.     {
  272.         return (NULL);
  273.     }
  274.     
  275.     return (texture);
  276. }
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.